//
// Created by Administrator on 2025/8/30.
//

#ifndef GB28181_SIP_REGISTER_HPP
#define GB28181_SIP_REGISTER_HPP

#include <jni.h>
#include <thread>
#include "eXosip2/eX_setup.h"

class SipRegister {
public:
    enum RegisterState {
        REG_STATE_IDLE,
        REG_STATE_SENT_INITIAL,
        REG_STATE_SENT_AUTH,
        REG_STATE_SUCCESS,
        REG_STATE_FAILED
    };

    explicit SipRegister() = default;

    /**
     * 初始化 eXosip 栈并向 GB28181 平台发起注册
     */
    void initialize(std::string &local_host,
                    std::string &server_host,
                    int server_port,
                    std::string &server_code,
                    std::string &server_domain,
                    std::string &device_code,
                    std::string &serial_number,
                    std::string &device_name,
                    std::string &password,
                    double longitude,
                    double latitude);

    /**
     * Sip信令回调
     */
    void setSipEventCallback(JNIEnv *env, jobject callback);

    /**
     * 注销（发送 expires=0 的 REGISTER）
     */
    void unregister();

    ~SipRegister();

private:
    eXosip_t *_ex_context{};
    int _reg_id{};
    std::atomic<bool> _running{false};
    std::thread *_sip_event_thread{};
    RegisterState _reg_state = REG_STATE_IDLE;
    bool _is_do_unregister = false;
    std::atomic<int> _sn_cache{1};
    std::thread *_heartbeat_thread = nullptr;
    std::atomic<bool> _heartbeat_running{false};
    std::string _local_rtp_ip;
    jobject _callback_obj{};
    JavaVM *_jvm{};

    std::string _local_host;
    std::string _server_host;
    int _server_port{};
    std::string _server_code;
    std::string _server_domain;
    std::string _device_code;
    std::string _serial_number;
    std::string _device_name;
    std::string _password;
    double _longitude{};
    double _latitude{};

    /**
     * Sip心跳
     */
    void heartbeat();

    /**
     * 事件循环
     * */
    void sipEventLoop();

    void registerSuccess();

    void registerFailed(osip_message_t *response);

    void sipMessage(eXosip_event_t *event);

    void startPushStream(eXosip_event_t *event);

    ////////////////////////////////////////////////////////////////////////////////////////////

    void callbackToJava(int code, const std::string &content);
};


#endif //GB28181_SIP_REGISTER_HPP
